package com.gp.billsrecord.ui.opt

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.asLiveData
import androidx.navigation.fragment.findNavController
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.bottomsheets.gridItems
import com.afollestad.materialdialogs.lifecycle.lifecycleOwner
import com.afollestad.materialdialogs.list.SingleChoiceListener
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import com.gp.billsrecord.databinding.FragmentMainMakeNoteBinding
import com.gp.billsrecord.base.BaseFragment
import com.gp.billsrecord.extensions.toMoney
import com.gp.billsrecord.model.data.AccountInfo
import com.gp.billsrecord.model.data.BillFlowInfo
import com.gp.billsrecord.model.data.ConsumptionType
import com.gp.billsrecord.util.DateUtil
import com.gp.billsrecord.vm.AppViewModel
import com.loper7.date_time_picker.DateTimeConfig
import com.loper7.date_time_picker.dialog.CardDatePickerDialog
import com.xujichang.base.extensions.postToast
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong

/*记一笔*/
class MakeNoteFragment : BaseFragment<FragmentMainMakeNoteBinding>() {
    private val viewModel by viewModels<AppViewModel>()

    //账户
    private val accounts = arrayListOf<AccountInfo>()

    //被选中的账户Index
    private val accountSelectIndex = AtomicInteger(-1)

    //消费类型
    private val consumeTypes = arrayListOf<ConsumptionType>()

    //被选中的消费类型Index
    private val consumeTypeSelectIndex = AtomicInteger(-1)

    private val createTimeMs = AtomicLong()

    /**
     * 初始化的东西
     */
    override fun onBindingCreated() {
        //收入的点击
        binding.ctvNoteIncome.setOnClickListener {
            binding.ctvNoteIncome.isChecked = true
            binding.ctvNoteOutlay.isChecked = false
        }
        //支出的点击
        binding.ctvNoteOutlay.setOnClickListener {
            binding.ctvNoteIncome.isChecked = false
            binding.ctvNoteOutlay.isChecked = true
        }
        //账户点击
        binding.tvNoteAccount.setOnClickListener {
            //选择账户
            doAccountSelect()
        }
        //消费类型点击
        binding.tvNoteConsumptionType.setOnClickListener {
            //选择消费类型
            doConsumptionSelect()
        }
        //日期的点击
        binding.tvNoteDate.setOnClickListener {
            //选择日期
            doDateSelect()
        }
        //备注的点击
        binding.tvNoteMark.setOnClickListener {
            //备注
            binding.tvNoteMark.toggle()
            changeMarkStatus()
        }
        //添加的点击
        binding.btnNoteAdd.setOnClickListener {
            checkAndObtainBillFlow()?.also { billflow ->
                //流水信息收集无误，存入数据库
                viewModel.addBillFlow(billflow).observe(viewLifecycleOwner) {
                    if (it) {
                        //添加成功，返回
                        findNavController().popBackStack()
                        postToast("添加成功")
                    } else {
                        postToast("添加失败")
                    }
                }
            }
        }
    }

    /**
     * 改变备注数据框的状态：显示还是不显示
     */
    private fun changeMarkStatus() {
        if (binding.tvNoteMark.isChecked) {
            binding.etNoteMark.visibility = View.VISIBLE
        } else {
            binding.etNoteMark.visibility = View.INVISIBLE
        }
    }

    /**
     *检测字段的合格性，并返回一条BillFlow记录
     */
    private fun checkAndObtainBillFlow(): BillFlowInfo? {
        val money = binding.etNoteBalance.text.toString()
        if (money.isEmpty()) {
            postToast("未输入金额")
            return null
        }
        //账户
        if (-1 == accountSelectIndex.get()) {
            postToast("未选择账户")
            return null
        }
        //根据Index取完整的账户信息
        val account = accounts[accountSelectIndex.get()]
        //消费类型
        if (-1 == consumeTypeSelectIndex.get()) {
            postToast("未选择消费类型")
            return null
        }
        //根据Index取完整的消费类型信息
        val consumeType = consumeTypes[consumeTypeSelectIndex.get()]
        //备注
        val mark = binding.etNoteMark.text.toString()
        //将输入的金额变为Long类型
        val realMoney = money.toDouble().times(100).toLong()
        //判断是否是收入
        val isIncome = binding.ctvNoteIncome.isChecked
        //如果是支出
        if (!isIncome && realMoney > account.balance) {
            postToast("账户余额不足")
            return null
        }
        //结算后剩余金额
        val remainMoney = if (isIncome) realMoney + account.balance else account.balance - realMoney
        return BillFlowInfo(
            realMoney,
            remainMoney,
            consumeType.typeId,
            consumeType.typeName,
            account.accountId,
            account.accountNumber,
            account.accountTypeName,
            mark,
            createTimeMs.get(),
            isIncome
        )
    }

    //日期弹框
    private fun doDateSelect() {
        CardDatePickerDialog.builder(requireContext())
            .setDisplayType(
                DateTimeConfig.MONTH,
                DateTimeConfig.DAY,
                DateTimeConfig.HOUR,
                DateTimeConfig.MIN
            )
            .setOnChoose {
                //被选中的时候的逻辑
                binding.tvNoteDate.text = DateUtil.formatDateTime(it, "YYYY/MM/dd HH:mm")
            }
            .showFocusDateInfo(false)
            .showBackNow(false)
            .build()
            .show()
    }

    /**
     * 消费类型选择
     */
    private fun doConsumptionSelect() {
        val items = consumeTypes.map { it.typeName }
        MaterialDialog(requireContext(), BottomSheet()).show {
            listItemsSingleChoice(
                items = items,
                initialSelection = consumeTypeSelectIndex.get(),
                selection = { _, index, text ->
                    consumeTypeSelectIndex.set(index)
                    binding.tvNoteConsumptionType.text = text
                })
            lifecycleOwner(viewLifecycleOwner)
        }
    }

    /**
     * 选择账户
     */
    @SuppressLint("SetTextI18n")
    private fun doAccountSelect() {
        //将账户数据数据转化为账户名称的集合
        val items = accounts.map { "${it.accountTypeName}:${it.accountNumber}" }
        MaterialDialog(requireContext(), BottomSheet()).show {
            listItemsSingleChoice(
                items = items,
                initialSelection = accountSelectIndex.get(),
                selection = { _, index, text ->
                    //选中某一项之后的逻辑
                    //记录选中的Index
                    accountSelectIndex.set(index)
                    val account = accounts[index]
                    //显示到账户的text上
                    binding.tvNoteAccount.text =
                        "${account.accountTypeName}(${account.accountNumber})"
                })
            lifecycleOwner(viewLifecycleOwner)
        }
    }

    /**
     *页面被创建后的逻辑
     */
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        //监听 消费类型
        viewModel.observeAccountsLiveData().observe(viewLifecycleOwner) {
            accounts.clear()
            accounts.addAll(it)
        }
        //监听 账户
        viewModel.observeConsumptionTypes().observe(viewLifecycleOwner) {
            consumeTypes.clear()
            consumeTypes.addAll(it)
        }
        //初始化默认值
        createTimeMs.set(System.currentTimeMillis())
        binding.tvNoteDate.text = DateUtil.formatNow()
    }
}
